package com.zhiche.lisa.bms.service.driver.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zhiche.lisa.bms.dao.mapper.driver.PriceconfOcMapper;
import com.zhiche.lisa.bms.dao.model.driver.PriceconfOc;
import com.zhiche.lisa.bms.pojo.vo.driver.PriceconfOcVO;
import com.zhiche.lisa.bms.service.driver.IPriceconfOcService;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 车型计价油耗 服务实现类
 * </p>
 *
 * @author zhaoguixin
 * @since 2018-08-30
 */
@Service
@Slf4j
public class PriceconfOcServiceImpl extends ServiceImpl<PriceconfOcMapper, PriceconfOc> implements IPriceconfOcService {

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @Override
    public Page<PriceconfOcVO> listByPage(Page<PriceconfOcVO> page) {
        if (Objects.isNull(page)) {
            log.error("PriceconfOcServiceImpl.listByPage param conditions must not be null");
            return null;
        }
        page.setOrderByField("gmt_create");
        page.setAsc(false);
        EntityWrapper<PriceconfOcVO> ew = whereCondition(page);
        List<PriceconfOcVO> list = baseMapper.selectByConditions(page, ew);
        page.setRecords(list);
        return page;
    }

    /**
     * 添加
     *
     * @param priceconfOcVO
     * @param br
     * @return
     */
    @Override
    public Integer add(PriceconfOcVO priceconfOcVO, BindingResult br) {

        log.info("PriceconfOcServiceImpl.add param : {}", priceconfOcVO);

        if (Objects.isNull(priceconfOcVO)) {
            log.error("PriceconfOcServiceImpl.add param form must not be null");
            throw new BaseException("表单不能为空");
        }

        // 时间格式化
        updateEffectiveAndInvateDate(priceconfOcVO);

        //表单验证
        verificationForm(br);

        //业务验证
        verificationBusiness(priceconfOcVO);


        //查询当前生效的记录，更新失效时间未添加记录的生效时间
        PriceconfOc currentOc = this.selectByEffectiveDateAndVehicleTypeId(priceconfOcVO.getVehicleTypeId(), priceconfOcVO.getEffectiveDate());
        if (Objects.nonNull(currentOc)) {
            currentOc.setInvalidDate(priceconfOcVO.getEffectiveDate());
            this.updateById(currentOc);
        }

        PriceconfOc mile = new PriceconfOc();
        BeanUtils.copyProperties(priceconfOcVO, mile);
        this.insert(mile);
        return mile.getId();
    }

    /**
     * 更新线路价格
     *
     * @param priceconfOcVO
     * @param br
     * @return
     */
    @Override
    public Boolean update(PriceconfOcVO priceconfOcVO, BindingResult br) {
        log.info("PriceconfOcServiceImpl.update param : {}", priceconfOcVO);

        if (Objects.isNull(priceconfOcVO)) {
            log.error("PriceconfOcServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("表单不能为空");
        }

        // 时间格式化
        updateEffectiveAndInvateDate(priceconfOcVO);

        //表单验证
        verificationForm(br);

        //业务验证
        verificationBusiness(priceconfOcVO);

        //查询当前生效的记录，更新失效时间未添加记录的生效时间
        PriceconfOc currentMile = this.selectByEffectiveDateAndVehicleTypeId(priceconfOcVO.getVehicleTypeId(), new Date());
        if (Objects.nonNull(currentMile)) {
            currentMile.setInvalidDate(priceconfOcVO.getEffectiveDate());
            this.updateById(currentMile);
        }

        PriceconfOc mile = new PriceconfOc();
        BeanUtils.copyProperties(priceconfOcVO, mile);
        return this.updateById(mile);
    }


    /**
     * 时间格式化
     *
     * @param priceconfOcVO
     */
    private void updateEffectiveAndInvateDate(PriceconfOcVO priceconfOcVO) {
        // 时间格式化
        if (Objects.nonNull(priceconfOcVO.getEffectiveDate())) {
            priceconfOcVO.setEffectiveDate(ToolCommonUtils.getStartOfDate(priceconfOcVO.getEffectiveDate()));
        }
        if (Objects.nonNull(priceconfOcVO.getInvalidDate())) {
            priceconfOcVO.setInvalidDate(ToolCommonUtils.getStartOfDate(priceconfOcVO.getInvalidDate()));
        }
    }


    /**
     * 删除线路信息
     *
     * @param id
     * @return
     * @throws BaseException
     */
    @Override
    public Boolean del(Integer id) throws BaseException {
        log.info("PriceconfOcServiceImpl.del param : {}", id);

        if (Objects.isNull(id) || id.equals(0)) {
            log.error("PriceconfOcServiceImpl.del param id must not be null");
            throw new BaseException("主键不能为空");
        }

        PriceconfOc priceconfOc = selectById(id);
        if (Objects.nonNull(priceconfOc)) {
            log.error("PriceconfOcServiceImpl.del mile is null");
            throw new BaseException("记录不存在");
        }

        Date today = new DateTime().withMillisOfDay(0).toDate();
        if (Objects.nonNull(priceconfOc.getEffectiveDate()) && 1 > priceconfOc.getEffectiveDate().compareTo(today)) {
            log.error("PriceconfOcServiceImpl.del mile can not delete");
            throw new BaseException("只能删除未生效的记录");
        }

        this.deleteById(id);

        //更新当前记录失效时间为空
        PriceconfOc currentOc = this.selectByEffectiveDateAndVehicleTypeId(priceconfOc.getVehicleTypeId(), new Date());
        if (Objects.nonNull(currentOc)) {
            currentOc.setInvalidDate(null);
            this.updateById(currentOc);
        }

        return true;
    }

    /**
     * 查询车型计价油耗
     *
     * @param id
     * @return
     */
    @Override
    public PriceconfOcVO getById(Integer id) {
        EntityWrapper<PriceconfOcVO> ew = new EntityWrapper<>();
        ew.eq("id", id);
        return baseMapper.getOneByEW(ew);
    }

    /**
     * 构建条件
     *
     * @param page
     * @return
     */
    private EntityWrapper<PriceconfOcVO> whereCondition(Page<PriceconfOcVO> page) {
        EntityWrapper<PriceconfOcVO> ew = new EntityWrapper<>();

        //查询条件
        if (Objects.nonNull(page.getCondition())) {
            //起运省
            if (Objects.nonNull(page.getCondition().get("vehicleTypeId")) && StringUtils.isNotEmpty(page.getCondition().get("vehicleTypeId").toString())) {
                ew.eq("vehicle_type_id", page.getCondition().get("vehicleTypeId").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("vehicleClassifyName")) && StringUtils.isNotEmpty(page.getCondition().get("vehicleClassifyName").toString())) {
                ew.like("vehicle_classify_name", page.getCondition().get("vehicleClassifyName").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("fuelTypeId")) && StringUtils.isNotEmpty(page.getCondition().get("fuelTypeId").toString())) {
                ew.eq("fuel_type_id", page.getCondition().get("fuelTypeId").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("currentValue")) && StringUtils.isNotEmpty(page.getCondition().get("currentValue").toString())) {
                ew.ge("current_value", page.getCondition().get("currentValue").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("effectiveDate")) && StringUtils.isNotEmpty(page.getCondition().get("effectiveDate").toString())) {
                ew.ge("effective_date", page.getCondition().get("effectiveDate").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("invalidDate")) && StringUtils.isNotEmpty(page.getCondition().get("invalidDate").toString())) {
                ew.lt("invalid_date", page.getCondition().get("invalidDate").toString().trim());
            }
        }

        return ew;
    }

    private void verificationForm(BindingResult br) {
        if (null == br) {
            log.error("PriceconfOcServiceImpl.verificationForm error br is null");
            throw new BaseException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            log.error("PriceconfOcServiceImpl.verificationForm error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    private void verificationBusiness(PriceconfOcVO form) {
        log.info("PriceconfOcServiceImpl.verificationBusiness param : {}", form);

        EntityWrapper<PriceconfOc> ew = new EntityWrapper<>();
        ew.eq("vehicle_type_id", form.getVehicleTypeId());
        ew.ge("effective_date", form.getEffectiveDate());
        ew.andNew().le("invalid_date", form.getEffectiveDate()).or().isNull("invalid_date");
        List<PriceconfOc> list = this.selectList(ew);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // /**
        //  * 是否已经存在未激活的油耗变动
        //  * 激活时间大于
        //  */
        // List<PriceconfOc> collect = list.stream().filter(
        //         o -> o.getEffectiveDate().compareTo(new DateTime().withMillisOfDay(0).toDate()) > -1
        // ).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(list)) {
            if (Objects.nonNull(form.getId())) {
                if (CollectionUtils.isNotEmpty(list.stream().filter(o -> o.getId().equals(form.getId())).collect(Collectors.toList()))) {
                    return;
                }
            }

            if (list.size() >= 1) {
                log.error("PriceconfOcServiceImpl.verificationBusiness already exist not active record");
                throw new BaseException("车型油耗已经存在未生效的记录");
            }

            PriceconfOc oc = list.get(0);
            if (Objects.nonNull(form.getId()) && form.getId().equals(oc.getId())) {
                return;
            }
            if (form.getEffectiveDate().compareTo(oc.getEffectiveDate()) == 1) {
                return;
            }

            log.error("ScPriceconfOcServiceImpl.verificationBusiness already exist not active record");
            throw new BaseException("车型油耗已经存在未生效的记录");
        }
    }

    @Override
    public PriceconfOc selectByEffectiveDateAndVehicleTypeId(Integer vehicleTypeId, Date effectiveDate) {
        log.info("ScPriceconfOcServiceImpl.selectByEffectiveDate params : {}, {}", vehicleTypeId, effectiveDate);

        if (Objects.isNull(vehicleTypeId) || vehicleTypeId.equals(0)) {
            log.error("ScPriceconfOcServiceImpl.selectByEffectiveDate param vehicleTypeId must not be null");
            throw new BaseException("车型分类主键不能为空");
        }
        if (effectiveDate == null) {
            log.error("ScPriceconfOcServiceImpl.selectByEffectiveDate param effectiveDate must not be null");
            throw new BaseException("生效时间不能为空");
        }

        EntityWrapper<PriceconfOc> ew = new EntityWrapper<>();
        ew.eq("vehicle_type_id", vehicleTypeId)
                .le("effective_date", effectiveDate)
                .and("invalid_date is NULL");

        List<PriceconfOc> list = this.selectList(ew);

        if (CollectionUtils.isEmpty(list)) {
            EntityWrapper<PriceconfOc> ew1 = new EntityWrapper<>();
            ew.eq("vehicle_type_id", vehicleTypeId)
                    .le("effective_date", effectiveDate)
                    .gt("invalid_date", effectiveDate);
            list = this.selectList(ew1);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }

}
